import { area } from "../../api";
import { storage } from "../../libs";
const debug = process.env.NODE_ENV !== "production";

const MUTATION_TYPES = {
  AREA_LIST: "AREA_LIST",
  PROCESSING: "PROCESSING",
  FROM_AREA: 'FROM_AREA',
  TO_AREA: 'TO_AREA'
};

class AreaCache {
  constructor() {
    this.areaMap = {};
  }
  make (areaList) {
    areaList?.forEach((area) => {
      this.areaMap[area.value] = area;
      let children = area.children;
      if (children?.length > 0) {
        this.make(area.children);
      }
    });
  }
  read () {
    let areaList = storage.read("AREA::areas");
    this.make(areaList);
    return areaList;
  }
  write (areaList) {
    this.make(areaList);
    storage.write("AREA::areas", areaList, 1800);
  }
}

const areaCache = new AreaCache();

const state = {
  areaList: [],
  processing: false,
  fromArea: {},
  toArea: {}
};
const getters = {};

const mutations = {
  [MUTATION_TYPES.AREA_LIST] (state, areaList) {
    state.areaList = areaList;
    areaCache.write(areaList);
  },
  [MUTATION_TYPES.PROCESSING] (state, processing) {
    state.processing = processing;
  },
  [MUTATION_TYPES.FROM_AREA] (state, fromArea) {
    state.fromArea = fromArea;
  },
  [MUTATION_TYPES.TO_AREA] (state, toArea) {
    state.toArea = toArea;
  }
};

const actions = {
  async load ({ commit }) {
    let areaList = areaCache.read();
    if (areaList) {
      commit(MUTATION_TYPES.AREA_LIST, areaList);
      return areaList;
    }
    if (state.processing) {
      return;
    }
    commit(MUTATION_TYPES.PROCESSING, true);
    let response = await area.load();
    if (response?.code === 0) {
      commit(MUTATION_TYPES.AREA_LIST, response.data);
      return response.data;
    }
  },
  setFromArea ({ commit }, fromArea) {
    commit(MUTATION_TYPES.FROM_AREA, fromArea);
  },
  setToArea ({ commit }, toArea) {
    commit(MUTATION_TYPES.TO_AREA, toArea);
  },
  closeArea ({ commit }) {
    commit(MUTATION_TYPES.FROM_AREA, {});
    commit(MUTATION_TYPES.TO_AREA, {});
  }
};

export default {
  strict: debug,
  namespaced: true,
  state,
  getters,
  mutations,
  actions
};

class AreaReader {
  constructor(name, code) {
    this.name = name;
    if (!areaCache.areaMap[code]) {
      areaCache.read();
    }
    Object.assign(this, areaCache.areaMap[code] || {});
  }
}

export { AreaReader };
